package get

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/urfave/cli/v2"
	"gluenet/internal/client/util"
	"gopkg.in/yaml.v3"
	"unicode"
)

const (
	cliUrl = "http://39.101.140.145:30000"
)

type ConfigBody struct {
	Code    int          `json:"code" yaml:"code"`
	Message string       `json:"message" yaml:"message"`
	Data    []ConfigData `json:"data" yaml:"data"`
}

type ConfigData struct {
	Id         string      `json:"id" yaml:"id"`
	Name       string      `json:"name" yaml:"name"`
	Kind       string      `json:"kind" yaml:"kind"`
	Platform   string      `json:"platform" yaml:"platform"`
	Describe   string      `json:"describe" yaml:"describe"`
	Version    string      `json:"version" yaml:"version"`
	Label      string      `json:"label" yaml:"label"`
	DetailInfo interface{} `json:"detail_info" yaml:"detail_info"`
	CreateTime string      `json:"create_time" yaml:"create_time"`
	UpdateTime string      `json:"update_time" yaml:"update_time"`
}

func config(ctx *cli.Context) error {
	//os.Getenv("GLUE_CONFIG")

	body, err := util.HttpRequest("GET", cliUrl+"/apis/config/all", nil)
	if err != nil {
		return err
	}

	err = parseConfig(ctx, body)
	return err
}

func parseConfig(ctx *cli.Context, body []byte) error {
	var (
		configBody ConfigBody
		idName     string
		filetype   string
	)

	err := json.Unmarshal(body, &configBody)
	if err != nil {
		return err
	}

	if ctx.Bool("all") {
		fmt.Printf("%-40s %-25s %-15s %-15s %-30s\n",
			"Id", "Name", "Kind", "Platform", "Label")
		fmt.Println("---------------------------------------------------------------------------" +
			"-----------------------------------------------------")
	} else {
		idName = ctx.String("id")
		filetype = ctx.String("output")
	}

	for _, configData := range configBody.Data {
		if ctx.Bool("all") {
			var name []byte
			nameLen := 25

			if len(configData.Name) < nameLen {
				cnt := 0
				for _, c := range configData.Name {
					if unicode.Is(unicode.Han, c) {
						cnt++
					}
				}

				slice := make([]byte, nameLen+cnt-len(configData.Name))
				for k := range slice {
					slice[k] = ' '
				}
				name = append([]byte(configData.Name), slice...)
			}

			fmt.Printf("%-40s %s %-15s %-15s %-30s\n",
				configData.Id, string(name), configData.Kind, configData.Platform, configData.Label)
		} else if configData.Id == idName || configData.Name == idName {
			var outString string
			switch filetype {
			case "yaml":
				yamlByte, _ := yaml.Marshal(configData)
				outString = string(yamlByte)
			case "json":
				jsonByte, _ := json.Marshal(configData)
				outString = string(jsonByte)
			default:
				err = errors.New("wrong config argument: please type \"json\" or \"yaml\"")
				return err
			}

			fmt.Print(outString)
			break
		}
	}
	return nil
}
